package com.zyy.jomap.resolve;

import com.github.javaparser.JavaParser;
import com.github.javaparser.ParseResult;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.ImportDeclaration;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.stmt.Statement;
import com.zyy.jomap.JoMapProcessor;
import com.zyy.jomap.constant.DebugConstant;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 解析Java文件--OK--Back----暂未用
 * 使用正则表达式匹配变量的类型--source
 * 先用使用ResolveJavaParser类实现Java文件解析
 */
public class ResolveJava {

    /** 匹配的正则表达式 **/
    private static String reg="(JoMap\\s*\\.\\s*copy(Bean|List|Map|Page)\\s*\\(([\\s\\S]*?)\\))";
    private static Pattern pattern = Pattern.compile(reg);
    private static Map<String, List<String>> varImportKeytargetImportListMap=new HashMap<>();

    public static void main(String[] args) throws FileNotFoundException {
        GenerateMapFile.resolveFile(null,null,null,null,null,null);
    }

    public static void doParse(List<String> javaAbsPathList){
        JavaParser javaParser=new JavaParser();
        for(String javaAbsPath:javaAbsPathList){
            parseClazz(javaParser,javaAbsPath);
        }
        JoMapProcessor.sPrintMsg("resolve java map: ",varImportKeytargetImportListMap.toString());
        //生成JAVA文件和class文件
        GenerateMapFile.doGenerateFile(varImportKeytargetImportListMap);
    }

    /**
     * 类解析
     * @param javaAbsPath  java文件绝对路径
     */
    public static void parseClazz(JavaParser javaParser,String javaAbsPath){
        //String javaAbsPath=getClazzAbsPath(clazzPath);
        ParseResult<CompilationUnit> result = null;
        try {
            result = javaParser.parse(Paths.get(javaAbsPath));
        } catch (IOException e) {
            e.printStackTrace();
        }
        CompilationUnit cu=result.getResult().get();
        List<ClassOrInterfaceDeclaration> clazzList=cu.findAll(ClassOrInterfaceDeclaration.class);
        ClassOrInterfaceDeclaration clazz=clazzList.get(0);
        Boolean clazzParseFlag=!clazz.getAnnotationByName("Get").equals(Optional.empty())||!clazz.getAnnotationByName("JavaBean").equals(Optional.empty());
        if(clazzParseFlag){
            return;
        }
        //import
        Map<String,String> typeNameKeyImpoertMap=new HashMap<>();
        NodeList<ImportDeclaration> importList=cu.getImports();
        for(ImportDeclaration importDeclaration:importList){
            //System.out.println("import:"+);
            String clazzImport=importDeclaration.getName().toString();
            int lastDotIndex=clazzImport.lastIndexOf(".");
            String typeName=clazzImport.substring(lastDotIndex+1,clazzImport.length());
            typeNameKeyImpoertMap.put(typeName,clazzImport);
        }
        List<MethodDeclaration> methodList=cu.findAll(MethodDeclaration.class);
        for(MethodDeclaration method:methodList){
            parseMethod(method,typeNameKeyImpoertMap);
            NodeList<Statement> statementList=method.getBody().get().getStatements();
            for(Statement statement:statementList){
                statement.getChildNodes();
            }
        }
        //注册访问者
        //cu.accept(new ClassVisitor(),null);
    }

    /**
     * 方法解析
     * @param method
     * @param typeNameKeyImpoertMap
     */
    public static void parseMethod(MethodDeclaration method,Map<String,String> typeNameKeyImpoertMap){
        NodeList<Parameter> paramList=method.getParameters();
        Map<String,String> paramNameKeyTypeMap=new HashMap<>();
        for(Parameter parameter:paramList){
            paramNameKeyTypeMap.put(parameter.getName().toString(),parameter.getTypeAsString());
        }
        String methodBody=method.getBody().toString();
        Matcher matcher = pattern.matcher(methodBody);
        while(matcher.find()){
            System.out.println("匹配到的语句:"+matcher.group(0));
            String type=matcher.group(matcher.groupCount());
            String[] typeArr=type.replace(" ","").split(",");
            String variableName=typeArr[0];
            String targetTypeName=typeArr[1].replace(".class","");
            String varTypeName=parseVariable(variableName,methodBody,paramNameKeyTypeMap);
            if(varTypeName!=null){
                String varImport=typeNameKeyImpoertMap.get(varTypeName);
                String targetImport=typeNameKeyImpoertMap.get(targetTypeName);
                if(varImport!=null&&targetImport!=null){
                    if(varImportKeytargetImportListMap.get(varImport)!=null){
                        varImportKeytargetImportListMap.get(varImport).add(targetImport);
                    }else if(varImportKeytargetImportListMap.get(targetImport)!=null){
                        varImportKeytargetImportListMap.get(targetImport).add(varImport);
                    }else{
                        List<String> targetImportList=new ArrayList<>();
                        targetImportList.add(targetImport);
                        varImportKeytargetImportListMap.put(varImport,targetImportList);
                    }
                }
            }
        }
    }

    /**
     * 变量和类型解析
     * @param variableName
     * @param methodBody
     * @param paramNameTypeMap
     * @return
     */
    public static String parseVariable(String variableName,String methodBody,Map<String,String> paramNameTypeMap){
        String typeReg="(\\s*((?!\\n).)*\\s*"+variableName+"\\s*(;|=))";
        Pattern typePattern=Pattern.compile(typeReg);
        Matcher typeMatcher=typePattern.matcher(methodBody);
        String varTypeName=null;
        //方法体内找到了变量的类型
        while(typeMatcher.find()){
            varTypeName=typeMatcher.group(0).trim();
            varTypeName=varTypeName.replace("\\s+"," ");
            varTypeName=varTypeName.split(" ")[0];
        }
        if(varTypeName==null){
            //方法体内未找到，判断方法参数列表
            varTypeName=paramNameTypeMap.get(variableName);
        }
        return varTypeName;
    }

    public static String getClazzAbsPath(String clazzPath){
        if(DebugConstant.DEBUG){
            String projectPath=System.getProperty("user.dir");
            projectPath=projectPath.replace("\\","/");
            projectPath=projectPath+"/"+DebugConstant.PROJECT_NAME+"/";
            clazzPath=clazzPath.replace(".java","").replace(".","/")+".java";
            return projectPath+"src/main/java/"+clazzPath;
        }
        String javaFileAbsPath= JoMapProcessor.projectDirAbsPath+clazzPath.replace(".java","").replace(".","/")+".java";
        return javaFileAbsPath;
    }

    public static String getPackageAbsPath(String packageName){
        String javaFileAbsPath= JoMapProcessor.projectDirAbsPath+packageName.replace(".","/");
        return javaFileAbsPath;
    }
}
